﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GN.Pay.Core.Entities;
using GN.Pay.TradeChannel.Transfers;
using GN.Pay.Core.Repositories;
using GN.Pay.Core.Exceptions;
using GN.Pay.TradeChannel;
using static GN.Pay.Core.Consts.ServiceConstant;

namespace GN.Pay.Core.Services.Impl
{
    /// <summary>
    /// 
    /// </summary>
    class TradeTransfersBookService : APayService, ITradeTransfersBookService
    {
        private readonly ITradeTransfersBookRepository repostiory;
        private readonly ITradeTransfersApplyRepository applyRepository;

        public TradeTransfersBookService(ITradeTransfersBookRepository repostiory,
            ITradeTransfersApplyRepository applyRepository)
        {
            this.repostiory = repostiory;
            this.applyRepository = applyRepository;
        }

        private void ApplyError(ITransfersApplyResult result)
        {
            var oldApply = this.applyRepository.Get(result.TransfersNo);
            if (oldApply == null)
            {
                result.ThrowChannelValidationException("无对应的转账申请号:" + result.TransfersNo);
            }
            oldApply.ApplyState = result.ResultState == TradeApplyResultState.Apply_Error ? TradeApplyState.Execute_Error : TradeApplyState.Execute_Balance_Error;
            oldApply.ApplyStateMessage = result.ResultStateMessage;
            this.applyRepository.Update(oldApply);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="result"></param>
        /// <param name="tradeTransfersApply"></param>
        /// <returns></returns>
        public TradeTransfersBook Accounting(ITransfersApplyResult result,
            out TradeTransfersApply tradeTransfersApply)
        {
            PayExceptionUtils.CheckNotNull(result, nameof(result));
            result.Validation();
            if (result.ResultState == TradeApplyResultState.Apply_Error
                || result.ResultState == TradeApplyResultState.Balance_Insufficient_Error)
            {
                //有错
                this.ApplyError(result);
                tradeTransfersApply = null;
                return null;
            }
            if (result.ResultState != TradeApplyResultState.Complete_Success)
            {
                //未完成，需等待
                tradeTransfersApply = null;
                return null;
            }
            var book = repostiory.Get(result.TransfersNo);
            if (book != null)
            {
                //已转账
                tradeTransfersApply = null;
                return null;
            }
            var apply = this.applyRepository.Get(result.TransfersNo);
            if (apply == null)
            {
                result.ThrowChannelValidationException("无对应的转账申请号:" + result.TransfersNo);
            }
            tradeTransfersApply = apply;
            book = new TradeTransfersBook()
            {
                Id = apply.Id,
                AppId = apply.AppId,
                AppIp = apply.AppIp,
                ApplyNo = apply.ApplyNo,
                ApplyTime = apply.ApplyTime,
                BookTime = DateTime.Now,
                ApplyMoney = apply.ApplyMoney,
                ChannelId = apply.ChannelId,
                AccountName = apply.AccountName,
                AccountNo = apply.AccountNo,
                Summary = apply.Summary,
                BankNo = apply.BankNo,
                ChannelTradeNo = result.TradeNo,
                ClientIp = apply.ClientIp,
                OpenBankName = apply.OpenBankName,
                ProvinceCity = apply.ProvinceCity,
                TransfersFee = result.TransfersFee,
                TransfersMoney = result.TransfersMoney,
                TransfersTime = result.TransfersTime == null ? DateTime.Now : result.TransfersTime.Value
            };
            this.repostiory.Insert(book);
            this.applyRepository.Delete(apply.Id);
            return book;
        }
    }
}
